%%% client_utils.erl

-module(client_utils).
-export([get_extension/1, update/0, receive_info/1, send_job/2])

get_extension(File) -> lists:nth(2, string:tokens(File, ".")).

update() -> c:l(client). % hotswap new code for the old code

receive_info(received_files) ->
	receive
		{success, received_files} ->
			{ok, {received_files}};
		Message ->
			{ok, {Message}}
	end;
receive_info(ready) ->
	receive
		ready ->
			{ok, {ready, send}};
		Message ->
			{error, {Message}}
	end;
receive_info(finished)    ->
	receive
		{finished, ok} ->
			{ok, {finished}};
		Message ->
			{error, {Message}}e
	end;
receive_info(solution)    ->
	receive
		{solution, Progress} when is_float(Progress) ->
			{solution, {Progress}};
		{solution, Progress} ->
			cluster_utils:print("Job has been complete, processing..."),
                        {ok, Server_Socket} = gen_tcp:connect(Socket, Address, [binary, {packet, 4}]),
                        {ok, Zipped_Data}   = gen_tcp:recv(Server_Socket, 0),
                        Result = zlib:unzip(Zipped_Data),
                        ok     = gen_tcp:close(Server_Socket),
                        cluster_utils:print("Proccessed~n"),
                        cluster_utils:print("Sending received result message to server..."),
			send_messages({Server, Job_ID}, [{received, result}]),
                        cluster_utils:print("Message sent~n"),
						{solution, {Result}}
	end;
receive_info(socket_info) ->
	receive
                {socket_info, {Socket, {0,0,0,0}}} -> %receive info; variables Socket and Address are now bound
			{socket_info, {Socket, "localhost"}};
		{socket_info, {Socket, Address}} ->
			{socket_info, {Socket, Address}};
                Message -> %if the message is anything else besides the clause above, exit
                       	{error, {'Bad data', Message}}
        end;
receive_info(job_id) ->
        receive
                {job_id, Job_ID} -> %receive job id from server, then write it out to a file, finally return the job id
                        cluster_utils:print("Received~n"),
                        ok = file:write_file(list_to_atom(atom_to_list(Job_ID) ++ ".txt"), list_to_binary(atom_to_list(Job_ID))),
                        {job_id, {Job_ID}};
                Message ->
                        {error, {'Bad data', Message}}
        end.

send_job(_, []) -> ok;
send_job(Socket, [Head|Tail]) ->
	ok = send_data(Socket, zlib:zip(Head)),
	send_job(Socket, Tail).

send_data(Socket, Zipped_Data) ->
        cluster_utils:print("Determining size of zipped data~n"),
        Length = length(integer_to_list(byte_size(Zipped_Data), 2)), % determine the size of the file in base2
        Zipped_Data_To_Send = list_to_binary(binary_to_list(<<Length:32>>) ++ binary_to_list(Zipped_Data)), % prepend the size to the beginning of the file
        cluster_utils:print("Waiting for server to be ready..."),
	{ok, {ready, send}} = client_utils:receive_info(ready), cluster_utils:print("Ready~n"),
        ok = gen_tcp:send(Socket, Zipped_Data_To_Send), % send the new data to the server
        cluster_utils:print("Waiting to receive finished message from server...~n"),
	{ok, {finished}} = client_utils:receive_info(finished).
